using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 项目清理结果
    /// </summary>
    public class ProjectCleanupResult
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; } = string.Empty;
        public List<string> CleanedFiles { get; set; } = new List<string>();
        public List<string> RenamedFiles { get; set; } = new List<string>();
        public List<string> RemovedFiles { get; set; } = new List<string>();
        public int TotalProcessed { get; set; }
    }

    /// <summary>
    /// 项目清理服务
    /// 用于清理重复文件、统一文件命名规范、移除错误信息和占位符内容
    /// </summary>
    public class ProjectCleanupService
    {
        private readonly ILogger<ProjectCleanupService> _logger;
        private readonly ContentQualityService _contentQualityService;

        public ProjectCleanupService(
            ILogger<ProjectCleanupService> logger,
            ContentQualityService contentQualityService)
        {
            _logger = logger;
            _contentQualityService = contentQualityService;
        }

        /// <summary>
        /// 清理整个项目
        /// </summary>
        public async Task<ProjectCleanupResult> CleanupProjectAsync(string projectPath)
        {
            var result = new ProjectCleanupResult();

            try
            {
                _logger.LogInformation($"开始清理项目: {projectPath}");

                if (!Directory.Exists(projectPath))
                {
                    result.IsSuccess = false;
                    result.Message = $"项目路径不存在: {projectPath}";
                    return result;
                }

                // 1. 清理重复文件
                await CleanupDuplicateFilesAsync(projectPath, result);

                // 2. 统一文件命名
                await StandardizeFileNamingAsync(projectPath, result);

                // 3. 清理文件内容
                await CleanupFileContentsAsync(projectPath, result);

                // 4. 移除空文件和无效文件
                await RemoveInvalidFilesAsync(projectPath, result);

                result.IsSuccess = true;
                result.Message = $"项目清理完成。处理文件: {result.TotalProcessed}, 清理: {result.CleanedFiles.Count}, 重命名: {result.RenamedFiles.Count}, 移除: {result.RemovedFiles.Count}";

                _logger.LogInformation(result.Message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理项目时发生错误");
                result.IsSuccess = false;
                result.Message = $"清理过程中发生错误: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// 清理重复文件
        /// </summary>
        private async Task CleanupDuplicateFilesAsync(string projectPath, ProjectCleanupResult result)
        {
            _logger.LogInformation("开始清理重复文件...");

            var chapterPath = Path.Combine(projectPath, "章节");
            if (!Directory.Exists(chapterPath))
                return;

            var chapterFiles = Directory.GetFiles(chapterPath, "*.txt", SearchOption.TopDirectoryOnly);
            var duplicateGroups = new Dictionary<string, List<string>>();

            // 按章节号分组
            foreach (var file in chapterFiles)
            {
                var chapterNumber = ExtractChapterNumber(Path.GetFileNameWithoutExtension(file));
                if (chapterNumber > 0)
                {
                    var key = $"第{chapterNumber:D3}章";
                    if (!duplicateGroups.ContainsKey(key))
                        duplicateGroups[key] = new List<string>();
                    duplicateGroups[key].Add(file);
                }
            }

            // 处理重复文件
            foreach (var group in duplicateGroups.Where(g => g.Value.Count > 1))
            {
                var files = group.Value.OrderBy(f => new FileInfo(f).LastWriteTime).ToList();
                var keepFile = files.Last(); // 保留最新的文件

                for (int i = 0; i < files.Count - 1; i++)
                {
                    var fileToRemove = files[i];
                    try
                    {
                        // 备份到临时目录
                        var backupDir = Path.Combine(projectPath, "备份", "重复文件");
                        Directory.CreateDirectory(backupDir);
                        var backupPath = Path.Combine(backupDir, Path.GetFileName(fileToRemove) + ".backup");
                        File.Move(fileToRemove, backupPath);

                        result.RemovedFiles.Add(Path.GetFileName(fileToRemove));
                        _logger.LogInformation($"移除重复文件: {Path.GetFileName(fileToRemove)}");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"移除重复文件失败: {fileToRemove}");
                    }
                }
            }
        }

        /// <summary>
        /// 统一文件命名规范
        /// </summary>
        private async Task StandardizeFileNamingAsync(string projectPath, ProjectCleanupResult result)
        {
            _logger.LogInformation("开始统一文件命名规范...");

            var chapterPath = Path.Combine(projectPath, "章节");
            if (!Directory.Exists(chapterPath))
                return;

            var chapterFiles = Directory.GetFiles(chapterPath, "*.txt", SearchOption.TopDirectoryOnly);

            foreach (var file in chapterFiles)
            {
                try
                {
                    var fileName = Path.GetFileNameWithoutExtension(file);
                    var standardName = StandardizeChapterFileName(fileName);

                    if (standardName != fileName)
                    {
                        var newPath = Path.Combine(Path.GetDirectoryName(file)!, standardName + ".txt");
                        
                        // 确保新文件名不存在
                        if (!File.Exists(newPath))
                        {
                            File.Move(file, newPath);
                            result.RenamedFiles.Add($"{fileName} -> {standardName}");
                            _logger.LogInformation($"重命名文件: {fileName} -> {standardName}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"重命名文件失败: {file}");
                }
            }
        }

        /// <summary>
        /// 清理文件内容
        /// </summary>
        private async Task CleanupFileContentsAsync(string projectPath, ProjectCleanupResult result)
        {
            _logger.LogInformation("开始清理文件内容...");

            // 清理章节文件
            await CleanupChapterContentsAsync(projectPath, result);

            // 清理大纲文件
            await CleanupOutlineContentsAsync(projectPath, result);
        }

        /// <summary>
        /// 清理章节内容
        /// </summary>
        private async Task CleanupChapterContentsAsync(string projectPath, ProjectCleanupResult result)
        {
            var chapterPath = Path.Combine(projectPath, "章节");
            if (!Directory.Exists(chapterPath))
                return;

            var chapterFiles = Directory.GetFiles(chapterPath, "*.txt", SearchOption.TopDirectoryOnly);

            foreach (var file in chapterFiles)
            {
                try
                {
                    var content = await File.ReadAllTextAsync(file);
                    var qualityResult = _contentQualityService.CheckChapterContent(content);

                    if (!string.IsNullOrEmpty(qualityResult.CleanedContent) && 
                        qualityResult.CleanedContent != content)
                    {
                        // 备份原文件
                        var backupPath = file + ".backup." + DateTime.Now.ToString("yyyyMMdd_HHmmss");
                        await File.WriteAllTextAsync(backupPath, content);

                        // 保存清理后的内容
                        await File.WriteAllTextAsync(file, qualityResult.CleanedContent);

                        result.CleanedFiles.Add(Path.GetFileName(file));
                        _logger.LogInformation($"清理章节内容: {Path.GetFileName(file)}");
                    }

                    result.TotalProcessed++;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"清理章节内容失败: {file}");
                }
            }
        }

        /// <summary>
        /// 清理大纲内容
        /// </summary>
        private async Task CleanupOutlineContentsAsync(string projectPath, ProjectCleanupResult result)
        {
            var outlinePaths = new[]
            {
                Path.Combine(projectPath, "大纲"),
                Path.Combine(projectPath, "大纲", "章节细纲"),
                Path.Combine(projectPath, "大纲", "分卷大纲")
            };

            foreach (var outlinePath in outlinePaths)
            {
                if (!Directory.Exists(outlinePath))
                    continue;

                var outlineFiles = Directory.GetFiles(outlinePath, "*.txt", SearchOption.TopDirectoryOnly);

                foreach (var file in outlineFiles)
                {
                    try
                    {
                        var content = await File.ReadAllTextAsync(file);
                        var qualityResult = _contentQualityService.CheckOutlineContent(content);

                        if (!string.IsNullOrEmpty(qualityResult.CleanedContent) && 
                            qualityResult.CleanedContent != content)
                        {
                            // 备份原文件
                            var backupPath = file + ".backup." + DateTime.Now.ToString("yyyyMMdd_HHmmss");
                            await File.WriteAllTextAsync(backupPath, content);

                            // 保存清理后的内容
                            await File.WriteAllTextAsync(file, qualityResult.CleanedContent);

                            result.CleanedFiles.Add(Path.GetFileName(file));
                            _logger.LogInformation($"清理大纲内容: {Path.GetFileName(file)}");
                        }

                        result.TotalProcessed++;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"清理大纲内容失败: {file}");
                    }
                }
            }
        }

        /// <summary>
        /// 移除无效文件
        /// </summary>
        private async Task RemoveInvalidFilesAsync(string projectPath, ProjectCleanupResult result)
        {
            _logger.LogInformation("开始移除无效文件...");

            var allTextFiles = Directory.GetFiles(projectPath, "*.txt", SearchOption.AllDirectories);

            foreach (var file in allTextFiles)
            {
                try
                {
                    var content = await File.ReadAllTextAsync(file);
                    
                    // 检查是否为空文件或只包含空白字符
                    if (string.IsNullOrWhiteSpace(content) || content.Trim().Length < 10)
                    {
                        // 移动到备份目录
                        var backupDir = Path.Combine(projectPath, "备份", "无效文件");
                        Directory.CreateDirectory(backupDir);
                        var backupPath = Path.Combine(backupDir, Path.GetFileName(file));
                        
                        // 确保备份文件名唯一
                        int counter = 1;
                        while (File.Exists(backupPath))
                        {
                            var nameWithoutExt = Path.GetFileNameWithoutExtension(file);
                            var ext = Path.GetExtension(file);
                            backupPath = Path.Combine(backupDir, $"{nameWithoutExt}_{counter}{ext}");
                            counter++;
                        }

                        File.Move(file, backupPath);
                        result.RemovedFiles.Add(Path.GetFileName(file));
                        _logger.LogInformation($"移除无效文件: {Path.GetFileName(file)}");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"检查文件失败: {file}");
                }
            }
        }

        /// <summary>
        /// 提取章节号
        /// </summary>
        private int ExtractChapterNumber(string fileName)
        {
            var match = Regex.Match(fileName, @"第(\d+)章");
            if (match.Success && int.TryParse(match.Groups[1].Value, out int chapterNumber))
            {
                return chapterNumber;
            }
            return 0;
        }

        /// <summary>
        /// 标准化章节文件名
        /// </summary>
        private string StandardizeChapterFileName(string fileName)
        {
            // 提取基本信息
            var bookNameMatch = Regex.Match(fileName, @"^([^_]+)");
            var volumeMatch = Regex.Match(fileName, @"第(\d+)卷");
            var chapterMatch = Regex.Match(fileName, @"第(\d+)章");
            var chapterTitleMatch = Regex.Match(fileName, @"第\d+章[_·](.+)$");

            if (!bookNameMatch.Success || !chapterMatch.Success)
                return fileName; // 无法解析，保持原名

            var bookName = bookNameMatch.Groups[1].Value;
            var volumeNumber = volumeMatch.Success ? int.Parse(volumeMatch.Groups[1].Value) : 1;
            var chapterNumber = int.Parse(chapterMatch.Groups[1].Value);
            var chapterTitle = chapterTitleMatch.Success ? chapterTitleMatch.Groups[1].Value : "";

            // 标准化格式：书名_第XX卷_第1卷_第XXX章_章节标题
            var standardName = $"{bookName}_第{volumeNumber:D2}卷_第{volumeNumber}卷_第{chapterNumber:D3}章";
            
            if (!string.IsNullOrEmpty(chapterTitle))
            {
                // 清理章节标题中的特殊字符
                chapterTitle = Regex.Replace(chapterTitle, @"[<>:""/\\|?*]", "");
                standardName += $"_{chapterTitle}";
            }

            return standardName;
        }
    }
}
